package com.ssm.changeunit;

import com.ssm.changeunit.persistance.BranchDAO;
import com.ssm.changeunit.persistance.BranchDTO;
import com.ssm.changeunit.persistance.ChangeUnitBranchDAO;
import com.ssm.changeunit.persistance.ChangeUnitBranchDTO;
import com.ssm.changeunit.persistance.ChangeUnitDAO;
import com.ssm.changeunit.persistance.ChangeUnitDTO;
import com.ssm.changeunit.persistance.ChangeUnitItemDAO;
import com.ssm.changeunit.persistance.ChangeUnitItemDTO;
import com.ssm.changeunit.persistance.ChildDAO;
import com.ssm.changeunit.persistance.ChildDTO;
import com.ssm.changeunit.persistance.ParentDAO;
import com.ssm.changeunit.persistance.ChildDTO;
import com.ssm.changeunit.persistance.ParentDTO;
import com.ssm.changeunit.persistance.PersistanceException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * ChangeUnit 클래스
 * 
 * @author 시리우스
 */
public class ChangeUnit extends AbstractProduct {
    private String changeUnitId;
    
    private ChangeUnitDAO changeUnitDAO;
    
    /**
     * 생성자
     * 
     * @param changeUnitId
     */
    public ChangeUnit(String changeUnitId) {
        this.changeUnitId = changeUnitId;
        
        this.changeUnitDAO = new ChangeUnitDAO();
    }

    /**
     * ChangeUnitId를 가져옵니다.
     * @return
     */
    public String getChangeUnitId() {
        return changeUnitId;
    }
    
    /**
     * ChangeUnitId를 가져옵니다.
     * @return
     */
    public void setChangeUnitId(String changeUnitId) throws PersistanceException {
        ChangeUnitDTO changeUnitDTO = changeUnitDAO.find(this.changeUnitId);
        
        changeUnitDTO.setChangeUnitId(changeUnitId);
        
        changeUnitDAO.update(changeUnitDTO);
    }

    /**
     * 로그를 가져옵니다.
     * 
     * @return
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public String getLog() throws PersistanceException {
        return changeUnitDAO.find(changeUnitId).getLog();
    }

    /**
     * 로그를 변경합니다.
     * 
     * @param log
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void setLog(String log) throws PersistanceException {
        ChangeUnitDTO changeUnitDTO = changeUnitDAO.find(changeUnitId);
        
        changeUnitDTO.setLog(log);
        
        changeUnitDAO.update(changeUnitDTO);
    }

    /**
     * 날짜를 가져옵니다.
     * 
     * @return
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public Date getDate() throws PersistanceException {
        return changeUnitDAO.find(changeUnitId).getDate();
    }

    /**
     * 날짜를 변경합니다.
     * 
     * @param time
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void setDate(Date date) throws PersistanceException {
        ChangeUnitDTO changeUnitDTO = changeUnitDAO.find(changeUnitId);
        
        changeUnitDTO.setDate((java.sql.Date)date);
        
        changeUnitDAO.update(changeUnitDTO);
    }
    
    /**
     * 시간을 가져옵니다.
     * 
     * @return
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public Date getTime() throws PersistanceException {
        return changeUnitDAO.find(changeUnitId).getTime();
    }

    /**
     * 시간을 변경합니다.
     * 
     * @param time
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void setTime(Date time) throws PersistanceException {
        ChangeUnitDTO changeUnitDTO = changeUnitDAO.find(changeUnitId);
        
        //TO-DO setting 다시 생각해보기
        //changeUnitDTO.setTime(time);
        
        changeUnitDAO.update(changeUnitDTO);
    }

    /**
     * User를 가져옵니다.
     * @return
     * @throws com.ssm.changeunit.ChangeUnitException
     */
    public String getUserId() throws PersistanceException {
        ChangeUnitDTO changeUnitDTO = changeUnitDAO.find(changeUnitId);

        return changeUnitDTO.getUserId();
    }

    /**
     * User를 변경합니다.
     * @param user
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void setUserId(String userId) throws PersistanceException {
        ChangeUnitDTO changeUnitDTO = changeUnitDAO.find(changeUnitId);
        
        changeUnitDTO.setUserId(userId);
        
        changeUnitDAO.update(changeUnitDTO);
    }

    /**
     * Branch를 가져옵니다.
     * @return
     * @throws com.ssm.changeunit.ChangeUnitException
     */
    public List<Branch> getBranchs() throws PersistanceException {
        ChangeUnitBranchDAO changeUnitBranchDAO = new ChangeUnitBranchDAO();
        BranchDAO branchDAO = new BranchDAO();
        List<Branch> branches = new ArrayList<Branch>();
        
        List<ChangeUnitBranchDTO> changeUnitBranchDTOs = changeUnitBranchDAO.findByChangeUnitId(changeUnitId);

        for(ChangeUnitBranchDTO changeUnitBranchDTO : changeUnitBranchDTOs) {
            BranchDTO branchDTO = branchDAO.find(changeUnitBranchDTO.getBranchName());

            Branch branch = null;
            
            try {
                branch = new BranchFactory().createProduct(branchDTO.getBranchName());
            }
            catch(CreateException ex) {
                throw new PersistanceException(ex);
            }

            branches.add(branch);
        }
        
        return branches;
    }

    /**
     * Branch를 추가합니다.
     * 
     * @param branch
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void addBranch(Branch branch) throws PersistanceException {
        ChangeUnitBranchDAO changeUnitBranchDAO = new ChangeUnitBranchDAO();
        
        ChangeUnitBranchDTO changeUnitBranchDTO = new ChangeUnitBranchDTO();        
        changeUnitBranchDTO.setBranchName(branch.getBranchName());
        changeUnitBranchDTO.setChangeUnitId(changeUnitId);
        
        changeUnitBranchDAO.insert(changeUnitBranchDTO);
    }
    
    /**
     * Branch를 삭제합니다.
     * 
     * @param branch
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void removeBranch(Branch branch) throws PersistanceException {
        ChangeUnitBranchDAO changeUnitBranchDAO = new ChangeUnitBranchDAO();
        
        changeUnitBranchDAO.delete(changeUnitId);
    }
    
    /**
     * ChangeUnitItem들을 가져옵니다.
     * @return
     */
    public List<ChangeUnitItem> getChangeUnitItems() throws PersistanceException {
        ChangeUnitItemDAO changeUnitItemDAO = new ChangeUnitItemDAO();
        
        List<ChangeUnitItemDTO> changeUnitItemDTOs = changeUnitItemDAO.findByChangeUnitId(changeUnitId);
        
        List<ChangeUnitItem> changeUnitItems = new ArrayList<ChangeUnitItem>();
        
        for(ChangeUnitItemDTO changeUnitItemDTO : changeUnitItemDTOs) {
            try {
                changeUnitItems.add(
                        new ChangeUnitItemFactory().createProduct(changeUnitItemDTO.getChangeUnitItemId())
                        );
            }
            catch(CreateException ex) {
                throw new PersistanceException(ex);
            }
        }
        
        return changeUnitItems;
    }
    
    /**
     * ChangeUnitItem을 추가합니다.
     * @param changeUnitItem
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void addChangeUnitItem(ChangeUnitItem changeUnitItem) throws PersistanceException {        
        changeUnitItem.setChangeUnit(this);
    }
    
    /**
     * ChangeUnit의 부모를 가져옵니다.
     * @return
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public List<ChangeUnit> getParents() throws PersistanceException {
        ParentDAO parentDAO = new ParentDAO();
        
        // 현재 ChangeUnitId를 기준으로 Parent를 가져옵니다.
        List<ParentDTO> parentDTOs = parentDAO.findByChangeUnitId(changeUnitId);
        
        List<ChangeUnit> parentChangeUnits = new ArrayList<ChangeUnit>();
        
        
        
        for(ParentDTO parentDTO : parentDTOs) {
            try {
                parentChangeUnits.add(
                        new ChangeUnitFactory().createProduct(parentDTO.getParentChangeUnitId())
                        );
            }
            catch(CreateException ex) {
                throw new PersistanceException(ex);
            }
        }
        
        return parentChangeUnits;
    }
    
    /**
     * 부모를 추가합니다.
     * 
     * @param changeUnit
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void addParent(ChangeUnit changeUnit) throws PersistanceException {
        ParentDAO parentDAO = new ParentDAO();
        
        ParentDTO parentDTO = new ParentDTO();
        
        parentDTO.setParentId(UUID.randomUUID().toString());
        parentDTO.setChangeUnitId(changeUnitId);
        parentDTO.setParentChangeUnitId(changeUnit.getChangeUnitId());
        
        parentDAO.insert(parentDTO);
    }
    
    /**
     * ChangeUnit의 자식을 가져옵니다.
     * @return
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public List<ChangeUnit> getChilds() throws PersistanceException {
        ChildDAO childDAO = new ChildDAO();
        
        // 현재 ChangeUnitId를 기준으로 Parent를 가져옵니다.
        List<ChildDTO> childDTOs = childDAO.findByChangeUnitId(changeUnitId);
        
        List<ChangeUnit> childChangeUnits = new ArrayList<ChangeUnit>();
        
        for(ChildDTO childDTO : childDTOs) {
            try {
                childChangeUnits.add(
                        new ChangeUnitFactory().createProduct(childDTO.getChildChangeUnitId())
                        );
            }
            catch(CreateException ex) {
                throw new PersistanceException(ex);
            }
        }
        
        return childChangeUnits;
    }
    
    /**
     * 자식을 추가합니다.
     * 
     * @param changeUnit
     * @throws com.ssm.changeunit.persistance.PersistanceException
     */
    public void addChild(ChangeUnit changeUnit) throws PersistanceException {
        ChildDAO childDAO = new ChildDAO();
        
        ChildDTO childDTO = new ChildDTO();
        
        childDTO.setChildId(UUID.randomUUID().toString());
        childDTO.setChangeUnitId(changeUnitId);
        childDTO.setChildChangeUnitId(changeUnit.getChangeUnitId());
        
        childDAO.insert(childDTO);
    }
}